﻿using Awsc.DataAcquisitionSys.Core.Common;
using Awsc.DataAcquisitionSys.Core.Model;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace Awsc.DataAcquisitionSys.Core.Databases
{

    public interface IRepository<T> where T : EntityBase
    {
        Task<T> GetByIdAsync(int Id);
        Task<T> GetByNameAsync(string name);
        Task<IQueryable<T>> GetAllAsync();
        Task<T> AddAsync(T entity);
        Task<T> UpdateAsync(T entity);
        Task<int> DeleteAsync(int id);

        Task<IQueryable<T>> QueryAsync(Expression<Func<T, bool>> predicate);
    }
    public class Repository<T> : IRepository<T> where T : EntityBase
    {
        private readonly AppDbContext appDbContext;

        public Repository(AppDbContext appDbContext)
        {
            this.appDbContext = appDbContext;
        }
        public async Task<T> GetByIdAsync(int Id)
        {
            var entity = await appDbContext.Set<T>().FindAsync(Id);
            return entity;
        }

        public async Task<IQueryable<T>> GetAllAsync()
        {
            var entities = appDbContext.Set<T>().AsQueryable();
            return entities;
        }

        public async Task<T> AddAsync(T entity)
        {
            appDbContext.Set<T>().Add(entity);
            await appDbContext.SaveChangesAsync();
            return entity;
        }
        public async Task<T> UpdateAsync(T entity)
        {
            var localEntity =await GetByIdAsync(entity.Id);
            appDbContext.Entry(localEntity).State = EntityState.Detached;
            appDbContext.Set<T>().Attach(entity);
            appDbContext.Entry(entity).State = EntityState.Modified;
            await appDbContext.SaveChangesAsync();
            return entity;
        }
        public async Task<int> DeleteAsync(int id)
        {
            var entity = await appDbContext.Set<T>().FindAsync(id);
            if (entity != null)
            {
                appDbContext.Set<T>().Remove(entity);
                return await appDbContext.SaveChangesAsync();
            }
            else
            {
                return 0; // 未找到实体
            }
        }

        public async Task<IQueryable<T>> QueryAsync(Expression<Func<T, bool>> predicate)
        {
            var query = appDbContext.Set<T>().Where(predicate).AsQueryable();
            return query;
        }

        public async Task<T> GetByNameAsync(string name)
        {
            ArgumentAssert.NotNullOrEmpty(name);
            var entity =await appDbContext.Set<T>().FirstOrDefaultAsync(s => s.Name == name);
            return entity;
        }
    }
}
